package com.lh.biz.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.lh.biz.BaseBiz;
import com.lh.biz.IUserBiz;
import com.lh.biz.dto.in.user.ForgetPasswordInDto;
import com.lh.biz.dto.in.user.LoginInDto;
import com.lh.biz.dto.in.user.RegisteInDto;
import com.lh.biz.dto.in.user.ResetPasswordInDto;
import com.lh.biz.dto.out.user.ForgetPasswordOutDto;
import com.lh.biz.dto.out.user.LoginOutDto;
import com.lh.biz.dto.out.user.RegisteOutDto;
import com.lh.cache.CacheManager;
import com.lh.common.logic.LoginLogic;
import com.lh.component.email.EmailFactory;
import com.lh.component.email.ForgetPasswordEmail;
import com.lh.dao.IUserDao;
import com.lh.entity.User;
import com.lh.entity.User.ForgetPasswordToken;
import com.lh.entity.User.UserStatus;
import com.lh.entity.User.UserType;
import com.lh.exception.BizException;
import com.lh.util.Crypt;

/**
 * @author liuhui
 * @version 1.0
 * @date 2013-4-29 上午10:08:38
 */
@Service
@Transactional
public class UserBizImpl extends BaseBiz implements IUserBiz {

	
	@Resource
	private IUserDao userDao;
	@Resource
	private LoginLogic loginLogic;
	@Resource
	private CacheManager cacheManager;
	@Resource
	private EmailFactory emailFactory;
	
	
	@Override
	public LoginOutDto login(LoginInDto inDto) {
		LoginOutDto out = new LoginOutDto();
		User u = userDao.selectByUsername(inDto.getName());
		if(u == null ){
			u = userDao.selectByEmail(inDto.getName());
		}
		if(u == null || !u.getPassword().equals(Crypt.md5(inDto.getPassword()))){
			out.setSuccess(false);
			out.setMessage(getMessage("user.login.error"));
			return out;
		}
		if(User.UserStatus.FROZEN.getValue().equals(u.getStatus())){
			out.setSuccess(false);
			out.setMessage(getMessage("user.login.statusError"));
			return out;
		}
		
		out.setSessionToken(loginLogic.execute(u , inDto.getRemoteAddress(), inDto.getCartId())  );
		return out;
	}




	@Override
	public RegisteOutDto registe(RegisteInDto inDto) throws BizException {
		User u = userDao.selectByUsername(inDto.getUsername());
		if(u != null){
			throw new BizException(getMessage("username.existed"));
		}
		if(!inDto.getPassword().equals(inDto.getPassword2())){
			throw new BizException(getMessage("password.notmatch"));
		}
		RegisteOutDto out = new RegisteOutDto();
		u = new User();
		u.setPassword(Crypt.md5(inDto.getPassword()));
		u.setRegisterTime(new Date());
		u.setStatus(UserStatus.NORMAL.getValue());
		u.setType(UserType.LOCAL.getValue());
		u.setUsername(inDto.getUsername());
		u.setEmail(inDto.getEmail());
		userDao.insert(u);
		out.setSessionToken(loginLogic.execute(u, inDto.getRemoteAddress() , inDto.getCartId()));
		return out;
	}




	@Override
	public ForgetPasswordOutDto forgetPassword(ForgetPasswordInDto inDto) {
		ForgetPasswordOutDto  out = new ForgetPasswordOutDto();
		User user = userDao.selectByEmail(inDto.getEmail());
		if(user == null ){
			out.setSuccess(false);
			out.setMessage(getMessage("user.emailNotExist"));
			return out;
		}
		
		String token = UUID.randomUUID().toString();
		ForgetPasswordToken forgetPasswordToken = new ForgetPasswordToken();
		forgetPasswordToken.setUsed(false);
		forgetPasswordToken.setToken(token);
		forgetPasswordToken.setUserId(user.getId());
		cacheManager.setValue(FIND_PASSWORD_CACHE_KEY_PREFIX + user.getId() , forgetPasswordToken, FORGET_PASSWORD_TOKEN_TIME_OUT);
		
		ForgetPasswordEmail email =emailFactory.getEmail(ForgetPasswordEmail.class);
		email.setSubmitTime(new Date());
		email.setToken(token);
		email.setId( user.getId() );
		email.send(inDto.getEmail() );
		return out;
	}




	@Override
	public void resetPassword(ResetPasswordInDto inDto) throws BizException {
		if(!inDto.getPassword().equals(inDto.getPassword2())){
			throw new BizException(getMessage("password.notmatch"));
		}
		User u = userDao.selectById(inDto.getId());
		if(u == null){
			throw new BizException(getMessage("user.notfound"));
		}
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("id", inDto.getId());
		param.put("password", Crypt.md5(inDto.getPassword()));
		userDao.update(param);
	}

}
